
import java.util.Scanner;

public class PCBScheduler {
    static class PCB {
        String name;
        String state;
        int cputime, count, needtime, round, priority;
    }

    static void Algorithm() {
        int i, n, max, j, y, count = 0;
        System.out.println("输入时间片");

        Scanner scanner = new Scanner(System.in);
        y = scanner.nextInt();
        System.out.println("输入进程数");
        n = scanner.nextInt();
        System.out.println("""
                
                
                
                
                1. round robin algorithm
                result：""");
        String[] ready = new String[n];
        String[] finish = new String[n];
        String[] wait = new String[n];
        scanner.nextLine();

        PCB[] pcb = new PCBScheduler.PCB[n];

        System.out.println("input name and needtime:");
        for (i = 0; i < n; i++) {
            String x;
            x = scanner.nextLine();
            String[] split = x.split(" ");
            String name = split[0];
            String needtime = split[1];

            PCB a = new PCBScheduler.PCB();
            a.name = name;
            a.needtime = Integer.parseInt(needtime);
            pcb[i] = a;
        }
        scanner.nextLine();
        max = pcb[0].needtime;
        for (i = 0; i < n; i++) {

            if (pcb[i].needtime > max)
                max = pcb[i].needtime;

        }
        int a = (int) Math.ceil(max / 2.0);
        for (i = 0; i < n; i++) {
            pcb[i].round = a;
            pcb[i].state = "W";
            pcb[i].cputime = 0;
            pcb[i].count = 0;
        }
        int[] w = new int[n];
        for (i = 0; i < n; i++) {
            w[i] = pcb[i].needtime;
        }
        while (true) {
            int k = 0, u = 0, z = 0;
            PCB t;
            t = new PCB();
            for (i = 0; i < n; i++) {
                if (pcb[i].state.equals("F") == false) {
                    pcb[i].state = "R";
                    break;
                }
            }
            for (i = 0; i < n; i++) {

                if (pcb[i].state.equals("R")) {
                    ready[z] = pcb[i].name;
                    z++;
                }
            }
            for (i = 0; i < n; i++) {
                if (pcb[i].state.equals("W")) {
                    wait[k] = pcb[i].name;
                    k++;
                }
            }
            for (i = 0; i < n; i++) {
                if (pcb[i].state.equals("F")) {
                    finish[u] = pcb[i].name;
                    u++;
                }
            }
            System.out.println("Name\ttime elapsed\ttime needed\tcount\tround\tstate");
            for (i = 0; i < n; i++) {
                System.out.printf("%-10s%-10d%-10d%-10d%-10d%-10s\n", pcb[i].name, pcb[i].cputime, pcb[i].needtime, pcb[i].count, pcb[i].round, pcb[i].state);
            }
            System.out.print("Ready query:");
            for (i = 0; i < k; i++) {
                System.out.print(wait[i] + " ");
            }
            System.out.printf("\n");
            System.out.print("Finished query：");
            for (i = 0; i < u; i++) {
                System.out.print(finish[i] + " ");
            }
            //输出
            System.out.printf("\n");
            if (finish[n - 1] != null) {
                break;
            }
            PCB b = new PCBScheduler.PCB();
            int d = 0;
            for (j = 0; j < n; j++) {
                if (pcb[j].needtime != 0) {
                    b = pcb[j];
                    d = w[j];
                    break;
                }
            }
            for (i = j + 1; i < n - count; i++) {
                pcb[i - 1] = pcb[i];
                w[i - 1] = w[i];
            }
            pcb[n - 1 - count] = b;
            w[n - 1 - count] = d;
            for (int r = y; r > 0; r--) {
                if ((pcb[n - 1 - count].cputime + r) <= w[n - 1 - count]) {
                    pcb[n - 1 - count].cputime = pcb[n - 1 - count].cputime + r;
                    break;
                }
            }
            pcb[n - 1 - count].needtime = pcb[n - 1 - count].needtime - y;
            pcb[n - 1 - count].count++;
            if (pcb[n - 1 - count].needtime <= 0) {
                pcb[n - 1 - count].needtime = 0;
                pcb[n - 1 - count].state = "F";
                b = pcb[n - 1 - count];
                for (i = 0; i < count; i++) {
                    pcb[n - count + i - 1] = pcb[n - count + i];
                }
                pcb[n - 1] = b;
                count++;
            } else {
                pcb[n - 1 - count].state = "W";
            }
        }
    }

    static void Priority() {
        int i, n, max = 0, c = 0, j, y, count = 0;
        System.out.println("输入时间片");
        Scanner scanner = new Scanner(System.in);
        y = scanner.nextInt();
        System.out.println("输入进程数");
        n = scanner.nextInt();
        String[] ready = new String[n];
        String[] finish = new String[n];
        String[] wait = new String[n];
        scanner.nextLine();
        PCB[] pcb = new PCBScheduler.PCB[n];
        System.out.println("input name and needtime:");
        for (i = 0; i < n; i++) {
            String x;
            x = scanner.nextLine();
            String[] split = x.split(" ");
            String name = split[0];
            String needtime = split[1];

            PCB a = new PCBScheduler.PCB();
            a.name = name;
            a.needtime = Integer.parseInt(needtime);
            a.priority = 50 - a.needtime;
            pcb[i] = a;
        }
        for (i = 0; i < n; i++) {
            pcb[i].state = "W";
            pcb[i].cputime = 0;
            pcb[i].count = 0;
        }
        for (i = 0; i < n - count; i++) {
            for (int e = i; e < n - count; e++) {
                if (pcb[i].priority < pcb[e].priority) {
                    PCB v = new PCB();
                    v = pcb[e];
                    pcb[e] = pcb[i];
                    pcb[i] = v;

                }
            }
        }
        int[] w = new int[n];
        for (i = 0; i < n; i++) {
            w[i] = pcb[i].needtime;
        }
        while (true) {
            int k = 0, u = 0, z = 0;
            PCB t;
            t = new PCB();
            for (i = 0; i < n; i++) {
                if (pcb[i].state.equals("F") == false) {
                    pcb[i].state = "R";
                    break;
                }
            }
            for (i = 0; i < n; i++) {

                if (pcb[i].state.equals("R")) {
                    ready[z] = pcb[i].name;
                    //  pcb[n]=pcb[i];

                    z++;
                }

            }
            for (i = 0; i < n; i++) {
                if (pcb[i].state.equals("W")) {
                    wait[k] = pcb[i].name;
                    // pcb[n+z+k]=pcb[i];
                    k++;
                }
            }
            for (i = 0; i < n; i++) {
                if (pcb[i].state.equals("F")) {
                    finish[u] = pcb[i].name;
                    // pcb[n+z+k+u]=pcb[i];
                    u++;
                }
            }
            System.out.printf("Name      cputime   needtime  count     pri       state\n");
            if (finish[n - 1] != null) {
                for (i = 0; i < n; i++) {
                    System.out.printf("%-10s%-10d%-10d%-10d%-10d%-10s\n", pcb[i].name, pcb[i].cputime, pcb[i].needtime, pcb[i].count, pcb[i].priority, pcb[i].state);

                }
            } else {
                for (i = 0; i < n - count; i++) {
                    System.out.printf("%-10s%-10d%-10d%-10d%-10d%-10s\n", pcb[i].name, pcb[i].cputime, pcb[i].needtime, pcb[i].count, pcb[i].priority, pcb[i].state);
                }
                for (i = n - 1; i > n - 1 - count; i--) {
                    System.out.printf("%-10s%-10d%-10d%-10d%-10d%-10s\n", pcb[i].name, pcb[i].cputime, pcb[i].needtime, pcb[i].count, pcb[i].priority, pcb[i].state);
                }
            }
            System.out.print("就绪队列:");
            for (i = 0; i < k; i++) {
                System.out.print(wait[i] + " ");
            }
            System.out.printf("\n");
            System.out.print("完成队列:");
            for (i = 0; i < u; i++) {
                System.out.print(finish[i] + " ");

            }
            //输出
            System.out.printf("\n");
            if (finish[n - 1] != null) {
                break;
            }
            PCB b = new PCBScheduler.PCB();
            int d = 0;
            for (i = 0; i < n - count; i++) {
                for (int e = i; e < n - count; e++) {
                    if (pcb[i].priority < pcb[e].priority) {
                        PCB v = new PCB();
                        v = pcb[e];
                        pcb[e] = pcb[i];
                        pcb[i] = v;

                    }
                }
            }
            for (j = 0; j < n; j++) {
                if (pcb[j].needtime != 0) {
                    b = pcb[j];
                    d = w[j];
                    break;
                }
            }
            for (i = j + 1; i < n - count; i++) {
                pcb[i - 1] = pcb[i];
                w[i - 1] = w[i];

            }
            pcb[n - 1 - count] = b;
            w[n - 1 - count] = d;
            for (int r = y; r > 0; r--) {
                if ((pcb[n - 1 - count].cputime + r) <= w[n - 1 - count]) {
                    pcb[n - 1 - count].cputime = pcb[n - 1 - count].cputime + r;
                    //  pcb[n-1-count].priority=pcb[n-1-count].priority-3;
                    break;
                }
            }
            pcb[n - 1 - count].needtime = pcb[n - 1 - count].needtime - y;
            pcb[n - 1 - count].count++;
            if (pcb[n - 1 - count].needtime <= 0) {
                pcb[n - 1 - count].needtime = 0;
                pcb[n - 1 - count].state = "F";

                b = pcb[n - 1 - count];
                for (i = 0; i < count; i++) {
                    pcb[n - count + i - 1] = pcb[n - count + i];
                }
                pcb[n - 1] = b;
                count++;
            } else {
                pcb[n - 1 - count].state = "W";
                pcb[n - 1 - count].priority = pcb[n - 1 - count].priority - 3;
            }
        }
    }

    public static void main(String[] args) {
        while (true) {
            int a;
            Scanner scanner = new Scanner(System.in);
            System.out.println("时间片输入1 优先级输入2 退出输入0");
            a = scanner.nextInt();
            switch (a) {
                case 0: {
                    return;
                }
                case 1: {
                    Algorithm();
                    break;
                }
                case 2: {
                    Priority();
                    break;
                }
            }
            scanner.nextLine();
            scanner.nextLine();
            scanner.nextLine();
            scanner.nextLine();
        }
    }


}
